package de.jmda.gen.java.impl;

import java.util.ArrayList;
import java.util.List;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import de.jmda.gen.Generator;
import de.jmda.gen.impl.AbstractCompoundGenerator;
import de.jmda.gen.java.MethodDetailsGenerator;
import de.jmda.gen.java.MethodHeaderGenerator;
import de.jmda.gen.java.MethodModifiersGenerator;
import de.jmda.gen.java.TypeNameGenerator;

public class DefaultMethodHeaderGenerator
		extends AbstractCompoundGenerator
		implements MethodHeaderGenerator
{
	private MethodModifiersGenerator modifiersGenerator;
	private @NotNull TypeNameGenerator typeNameGenerator;
	private @NotNull MethodDetailsGenerator methodDetailsGenerator;

	public DefaultMethodHeaderGenerator()
  {
		this(null, null, null);
  }

	public DefaultMethodHeaderGenerator(
      MethodModifiersGenerator modifiersGenerator,
      TypeNameGenerator typeNameGenerator,
      MethodDetailsGenerator methodDetailsGenerator)
  {
	  super();

	  setModifiersGenerator(modifiersGenerator);
	  setTypeNameGenerator(typeNameGenerator);
	  setMethodDetailsGenerator(methodDetailsGenerator);

    setComponentSeparator(" ");
  }

	/**
	 * Returns collection of <code>Generator</code>s with the return values
	 * of the following methods in the following order:
	 * <ul>
	 *   <li>{@link #getModifiersGenerator()},</li>
	 *   <li>{@link #getTypeNameGenerator()} and</li>
	 *   <li>{@link #getMethodDetailsGenerator()}</li>
	 * </ul>
	 * 
	 * @see de.jmda.gen.CompoundGenerator#getGeneratorComponents()
	 */
	@Override
  @NotNull
  @Valid
  public List<Generator> getGeneratorComponents()
  {
		List<Generator> result = new ArrayList<Generator>();

		result.add(getModifiersGenerator());
		result.add(getTypeNameGenerator());
		result.add(getMethodDetailsGenerator());

		return result;
  }

	@Override
  public MethodModifiersGenerator getModifiersGenerator()
  {
	  return modifiersGenerator;
  }

	@Override
	@NotNull
  public TypeNameGenerator getTypeNameGenerator()
  {
	  return notNull(typeNameGenerator);
  }

	@Override
	@NotNull
  public MethodDetailsGenerator getMethodDetailsGenerator()
  {
	  return notNull(methodDetailsGenerator);
  }

	@Override
  public void setModifiersGenerator(MethodModifiersGenerator generator)
  {
		modifiersGenerator = generator;
  }

	@Override
  public void setTypeNameGenerator(@NotNull TypeNameGenerator generator)
  {
		typeNameGenerator = notNull(generator);
  }

	@Override
  public void setMethodDetailsGenerator(@NotNull MethodDetailsGenerator generator)
  {
		methodDetailsGenerator = notNull(generator);
  }

	/**
	 * @NotNull
	 * @see de.jmda.gen.java.MethodHeaderGenerator#demandModifiersGenerator()
	 */
	@Override
	public MethodModifiersGenerator demandModifiersGenerator()
  {
		modifiersGenerator = notNull(modifiersGenerator);
	  return modifiersGenerator;
  }

	private TypeNameGenerator notNull(TypeNameGenerator generator)
  {
		if (generator == null)
		{
			generator = new DefaultTypeNameGenerator();
		}

		return generator;
  }

	private MethodDetailsGenerator notNull(MethodDetailsGenerator generator)
  {
		if (generator == null)
		{
			generator = new DefaultMethodDetailsGenerator();
		}

		return generator;
  }

	private MethodModifiersGenerator notNull(MethodModifiersGenerator generator)
  {
		if (generator == null)
		{
			generator = new DefaultMethodModifiersGenerator();
		}

		return generator;
  }
}